using Godot;
using System;

using CurrentGame.NPC;
using CurrentGame.Placements;
using CurrentGame.GUI.PlaceGrid;

namespace CurrentGame.Levels.SepLevel1;

public partial class SepLevel1Main : Node
{
    [Export]
    public Godot.Collections.Array<ShadeCharacter> ReadyShades { get; set; } = [];

    [Export]
    public ShadeCharacter MainShade { get; set; }
    [Export]
    public Timer DeltaTimer { get; set; }

    [ExportGroup("Areas")]
    [Export]
    public Area2D Talk1Area { get; set; }
    [Export]
    public Area2D TeleportArea { get; set; }
    [Export]
    public Area2D Talk3Area { get; set; }
    [Export]
    public Area2D FinalArea { get; set; }
    [Export]
    public Area2D LeavingArea { get; set; }

    [ExportGroup("Place texts")]
    [Export]
    public PlacableTexts PText1 { get; set; }
    [Export]
    public PlacableTexts PText2 { get; set; }
    [Export]
    public PlacableTexts PText3 { get; set; }
    [Export]
    public PlacableTexts PText4 { get; set; }
    [Export]
    public PlacableTexts PText5 { get; set; }

    [ExportGroup("Position marks")]
    [Export]
    public Node2D Talk1Anchor { get; set; }
    [Export]
    public Node2D ShadeWaitPosition { get; set; }
    [Export]
    public Node2D ShadeWait2Position { get; set; }
    [Export]
    public Node2D Talk2Anchor { get; set; }
    [Export]
    public Node2D Talk3Anchor { get; set; }
    [Export]
    public Node2D FinalAnchor { get; set; }
    [Export]
    public Node2D YetAnotherFinalAnchor { get; set; }

    [ExportGroup("Dialogue")]
    [Export]
    public DialogueConfig Dialogue1 { get; set; }
    [Export]
    public DialogueConfig Dialogue2 { get; set; }


    private Player _player;
    private SceneSwitch _sceneSwitch;
    private PlaceModeGrid _placeGrid;
    private GamePlayGui _gamePlayGui;
    private CinematicCamera _cinematicCamera;

    private int _talkState = 0;
    private bool _teleported = false;
    private bool _dialogue1Finished = false;


    public override void _Ready()
    {
        var map = GetNode<NodeReferenceMap>(Constants.NodeRefMapPath);
        _sceneSwitch = map.SceneSwitch;
        _sceneSwitch.SceneStart += Signal_SceneStart;
        _player = map.MainPlayer;
        _gamePlayGui = map.MainGui;
        _cinematicCamera = map.GameCamera;
        _placeGrid = map.PlacementModeGrid;

        _player.AttackEnabled = false;
        _player.DisablePlaceMode();
        _player.PlaceModeAvailable = false;
        _player.SetHealthPoint(3);
        _player.EnableInputCheck(true);
        _player.HealthPointChanged += Signal_TalkAreaEnter2;
        _gamePlayGui.SingleLineFinished += Signal_MultilineFinished;
        _gamePlayGui.DialogueBoxFinished += Signal_DialogueFinished;
        _placeGrid.FreePlaceCost = true;
    }

    public override void _ExitTree()
    {
        _sceneSwitch.SceneStart -= Signal_SceneStart;
        _gamePlayGui.SingleLineFinished -= Signal_MultilineFinished;
        _gamePlayGui.DialogueBoxFinished -= Signal_DialogueFinished;
        _player.HealthPointChanged -= Signal_TalkAreaEnter2;
        _placeGrid.ClearAllShade();
    }

    private void Signal_SceneStart()
    {
        GD.Print("Started");
        foreach (var shade in ReadyShades)
        {
            shade.ActivateFallDetection();
            _placeGrid.AppendReadyShade(shade);
        }
    }

    private void Signal_TalkAreaEnter1(Area2D area)
    {
        // Trigger area talk 1
        _talkState = 10;
        Talk1Area.QueueFree();
        _gamePlayGui.CinematicMode = true;
        _player.SkipInputCheck();
        _gamePlayGui.SetFloatingAnchor(Talk1Anchor);
        _gamePlayGui.ShowMultipleText([
            "诶...？",
            "没想到还有比我更慢的人啊~",
            "=v=",
            "快走吧，很快这片区域就没有光了。"
        ], [
            new Vector3(2.0f, 5.0f, 0.1f),
            new Vector3(2.0f, 10.0f, 0.3f),
            new Vector3(1.0f, -1f, 0.3f),
            new Vector3(2.0f, 10.0f, 0.1f)
        ]);
    }

    private void Signal_MultilineFinished()
    {
        if (_talkState == 10)
        {
            _talkState = 11;
            _gamePlayGui.CinematicMode = false;
            _player.EnableInputCheck();
            _gamePlayGui.ResetFloatingAnchor();

            DeltaTimer.WaitTime = 2.0f;
            DeltaTimer.Start();
        }
        else if (_talkState == 20)
        {
            _gamePlayGui.CinematicMode = false;
            _player.EnableInputCheck();
            _gamePlayGui.ResetFloatingAnchor();

            _player.PlaceModeAvailable = true;
            DeltaTimer.WaitTime = 2.0f;
            DeltaTimer.Start();
        }
        else if (_talkState == 30)
        {
            _gamePlayGui.CinematicMode = false;
            _player.EnableInputCheck();
            _gamePlayGui.ResetFloatingAnchor();

            DeltaTimer.WaitTime = 2.0f;
            DeltaTimer.Start();
        }
    }

    private void Signal_DialogueFinished()
    {
        if (_talkState == 12)
        {
            MainShade.UpdatePositionFallback(ShadeWaitPosition.GlobalPosition);
            MainShade.TeleportTo(ShadeWaitPosition.GlobalPosition);
            Dialogue1.QueueFree();
            _teleported = true;
            _dialogue1Finished = true;
        }
        else if (_talkState == 41)
        {
            _player.AttackEnabled = true;
            DeltaTimer.WaitTime = 2.0f;
            DeltaTimer.Start();

            _talkState = 42;
        }
    }

    private void Signal_TeleportAreaEnter(Area2D area)
    {
        if (!_teleported)
        {
            MainShade.TeleportTo(ShadeWaitPosition.GlobalPosition);

            if (!_dialogue1Finished)
            {
                Dialogue1.QueueFree();
            }
        }
        TeleportArea.QueueFree();
    }

    private void Signal_FinalAreaEnter(Area2D area)
    {
        if (_talkState == 30)
        {
            _talkState = 40;
        }
    }

    private void Signal_FinalAreaLeave(Area2D area)
    {
        if (_talkState == 40)
        {
            _talkState = 41;
            FinalArea.QueueFree();

            // Teleport shade to final anchor
            MainShade.TeleportTo(FinalAnchor.GlobalPosition);
            // Teleport dialogue
            Dialogue2.GlobalPosition = FinalAnchor.GlobalPosition;
            Dialogue2.ResetPhysicsInterpolation();
        }
    }

    private void Signal_TalkAreaEnter2(int hp)
    {
        if (_talkState == 12)
        {
            _talkState = 20;
            _gamePlayGui.CinematicMode = true;
            _player.SkipInputCheck();
            _gamePlayGui.SetFloatingAnchor(Talk2Anchor);
            _gamePlayGui.ShowMultipleText([
                "哦！...",
                "你看起来不太好。",
                "或许你不太喜欢光？",
                "...也许你可以让我帮你挡挡。",
                "=v="
            ], [
                new Vector3(1.0f, 20.0f, 0.3f),
                new Vector3(2.0f, 10.0f, 0.1f),
                new Vector3(2.0f, 10.0f, 0.3f),
                new Vector3(2.0f, 10.0f, 0.3f),
                new Vector3(1.0f, -1f, 0.3f)
            ]);
        }
    }

    private void Signal_TalkAreaEnter3(Area2D area)
    {
        if (_talkState == 20)
        {
            _talkState = 30;
            _gamePlayGui.CinematicMode = true;
            _player.SkipInputCheck();
            MainShade.UpdatePositionFallback(ShadeWait2Position.GlobalPosition);
            MainShade.TeleportTo(ShadeWait2Position.GlobalPosition);
            _gamePlayGui.SetFloatingAnchor(Talk3Anchor);
            _gamePlayGui.ShowMultipleText([
                " ",
                "=v=",
                "你看起来不够高啊。",
                "如果你愿意的话...",
                "我还是可以帮忙呦。",
            ], [
                new Vector3(1.0f, -1f, 0.3f),
                new Vector3(1.0f, 1.0f, 0.1f),
                new Vector3(1.0f, 30.0f, 0.3f),
                new Vector3(2.0f, 10.0f, 0.3f),
                new Vector3(2.0f, 10.0f, 0.3f),
            ]);
        }
    }

    private void Signal_TimerTimeout()
    {
        if (_talkState == 20)
        {
            PText1.ShowText = true;
        }
        else if (_talkState == 11)
        {
            PText2.ShowText = true;
            _talkState = 12;
        }
        else if (_talkState == 30)
        {
            PText3.ShowText = true;
        }
        else if (_talkState == 42)
        {
            PText4.ShowText = true;
        }
    }

    private void Signal_DisablePlaceMode(Area2D area)
    {
        if (_talkState == 30)
        {
            _player.DisablePlaceMode();
            _player.PlaceModeAvailable = false;
        }
    }

    private void Signal_LeavingAreaEnter(Area2D area)
    {
        if (_talkState == 42)
        {
            LeavingArea.QueueFree();
            Dialogue2.QueueFree();
            MainShade.TeleportTo(YetAnotherFinalAnchor.GlobalPosition);
            _player.PlaceModeAvailable = true;
            PText5.ShowText = true;
            _talkState = 50;
        }
    }
}
